package com.wanka.jutou.converter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.*;

/**
 * @author yangqing
 * @version 1.0
 * @date 2025/9/1 17:21
 * @description
 */
public abstract class SentinelConverter<T> implements Converter<String, Collection<Object>> {
    private static final Logger log = LoggerFactory.getLogger(SentinelConverter.class);
    private final ObjectMapper objectMapper;
    private final Class<T> ruleClass;

    public SentinelConverter(ObjectMapper objectMapper, Class<T> ruleClass) {
        this.objectMapper = objectMapper;
        this.ruleClass = ruleClass;
    }

    public Collection<Object> convert(String source) {
        Collection<Object> ruleCollection;
        if (this.ruleClass != FlowRule.class && this.ruleClass != DegradeRule.class && this.ruleClass != SystemRule.class && this.ruleClass != AuthorityRule.class && this.ruleClass != ParamFlowRule.class) {
            ruleCollection = new HashSet();
        } else {
            ruleCollection = new ArrayList();
        }

        if (StringUtils.isEmpty(source)) {
            log.info("converter can not convert rules because source is empty");
            return ruleCollection;
        } else {
            try {
                for(Object obj : (List)this.objectMapper.readValue(source, new TypeReference<List<HashMap>>() {
                })) {
                    try {
                        String item = this.objectMapper.writeValueAsString(obj);
                        Optional.ofNullable(this.convertRule(item)).ifPresent((convertRule) -> ruleCollection.add(convertRule));
                    } catch (IOException e) {
                        log.error("sentinel rule convert error: " + e.getMessage(), e);
                        throw new IllegalArgumentException("sentinel rule convert error: " + e.getMessage(), e);
                    }
                }

                return ruleCollection;
            } catch (Exception e) {
                if (e instanceof RuntimeException) {
                    throw (RuntimeException)e;
                } else {
                    throw new RuntimeException("convert error: " + e.getMessage(), e);
                }
            }
        }
    }

    private Object convertRule(String ruleStr) throws IOException {
        return this.objectMapper.readValue(ruleStr, this.ruleClass);
    }
}